Create a batch of statements¶
Let’s recall the task Take the ball on the neighboring square. The task was that in every direction, Karel needed to try to go to the neighboring square and (if he could go to the neighboring square) to try and get the ball there. In order to make trying the next direction easier, we chose to return Karel to the starting square after each attempt.
One program that solves that task is:
The part of the program from the seventh to the eleventh line seems a little tougher to follow. In that part, you might need to imagine Karel executing statements to fully understand what is happening there.
Comments somewhat help making this part of the program easier to understand. In addition to the comments, it would be even better if there was a function back(), which would move Karel a step back. Then the program would be shorter and more intelligible:
The function back() is not a part of the Karel library, but we can very easily write this function ourselves. When done, we will be able to use the function back() equally with the other functions of the Karel library, such as move() or turn_right().
How to write functions¶
For now, we will only learn the simplest way of writing a function in Python, and we will see other, more complex forms later.
When writing any function in Python, the word def
at the beginning, brackets ()
and a colon character :
at the end of the first row are mandatory. For function_name we can use any correctly written name that we choose. The following statements are written indented, and they form the body of the function (if more than one command is written in a row, then these commands are separated by a semicolon ;
). The statements in the function body will be executed each time the function name is encountered when running the program, that is, when this function is called.
In accordance to these rules, the function back() can be written as follows:
Then the whole program would look like this:
When we extract some statements (that have a meaning as a group) into a function, we can write programs that are shorter and clearer, because we have broken down the problem into less complex parts.
Another advantage of writing functions is that we can easily use them in other programs (here, we will occasionally copy previously written functions, but, in real programming, there is a better and simpler way to reuse once written functions).
Exiting the function or loop before its end¶
In the task of searching for the ball on a neighboring square, for the sake of the simplicity of the program, we decided that even when Karel finds a ball, he continues to search in the remaining directions. There is a way to avoid this unnecessary execution of the remaining statements.
When we want to interrupt a loop execution, we write a special break
statement. The effect of the break statement is to jump out of the loop and continue the execution of the program from the first statement after the loop.
By using a break statement, we will jump out of the nearest (narrowest) for or while loop containing the break statement. If a break statement is located inside two or more nested loops, the execution continues with the statement that follows the innermost (narrowest) loop.
Using the break statement, we could modify the main part of the program:
into:
This way, the loop ends as soon as the ball is found and taken. Since there are no other statements after this loop, in this case, by executing the break statement, the operation of the program finishes.
Similarly to exiting the loop, we can also exit the function before all its statements are executed.
When we want to interrupt the execution of a function, we write a special return
statement. The effect of the return statement is to jump out of the function and continue executing the program from the first statement after the place the function was called from.
With a return statement we jump out of the function no matter how many loops there are around the return statement inside the function.
We can turn the program for taking the ball on a neighboring field into a function. In that case, we could write:
Tasks for exercise¶
Drop the balls while there are both balls and squares¶
Initially, Karel has several balls and should arrange them along the path one at every square (starting from the square where he stands) as far as possible. Karel stops placing balls when he hits an obstacle or when he runs out of balls (whatever happens first). It does not matter if Karel will stop at the last filled square, or at the first empty square.
Hint: Put one of these two conditions into a while loop, so that the loop ends when the condition is no longer met. Additionally, use the break statement to exit the loop if the other condition is not met.
Move all the balls one square backwards¶
There is a path of unknown lenght in front of Karel. There are no balls in the starting square. Karel should shift each ball one square to the west.
You can solve this task by repeating the following steps as long as there are squares in front of Karel:
go to the next square
Take all the balls from that square
go a step back (that is, turn around and go one step ahead)
drop all the balls
go back to the square from which you took the balls
In doing so, you can use the previously written function back() to return to the square to which Karel moves the balls. You just need to copy it (or re-type it) to the area for your solution.
Follow the balls¶
Each square contains one ball or none. Squares with the balls on them form a path, which begins on the square next to Karel. Karel should follow this path and pick up all the balls.
Hint: To solve this task, you can write the function go_to_neighboring_nonempty_square(), which only needs to move Karell to the neighboring square which has a ball on it (the return statement can be useful there). The function go_to_neighboring_nonempty_square() should differ from the previously written function take_at_neighboring_square() only in the sense that it does not take the ball.
When Karel collects all the balls, the next call of this function will place him on an empty square (by the way, this will be the square where Karel took the last ball). When there is no ball on the square which Karel is on, this will mean that Karel has already taken all the balls.
Take all the balls from the whole table¶
Karel is initially facing north (up), and he is located in the lower left corner of a rectangular table of unknown size, with no interior walls. There can be any number of balls on each square. Karel should take all the balls from all the squares on the board.
Hint: Write a function empty_one_row(), which makes Karel:
turn left (to the east), looking along the row he is in
pass through the entire row and take all the balls from each square in that row, including the square he started on
turn to the beginning of the row (i.e. to the west)
return to the beginning of the row and turn north (up), as he stood before the function call
The program that solves the task using this function is not long. It needs to do the following:
empty the first row
while there are rows in front of Karel, go to the next one and empty it